<template>
    <div class="map-box">
         <div id="map" class="myMap">
        </div>
        <div class="drawBox">
            <el-row>
                <el-button type="primary" @click="drawRoad">开始绘制</el-button>
                <el-button type="primary" @click="cancelRoad">取消清除</el-button>
                <el-button type="primary" class="primary" @click="downloadFile">保存</el-button>
            </el-row>
        </div>
        <!-- 
        <el-button type="primary" class="upload" @click="drawRoad">分割区块</el-button> -->
    </div> 
</template>

<script>
import FeatureStyle from '@/assets/dist/FeatureStyle'
import drawFence from '@/assets/dist/mapTools';
import { saveAs } from 'file-saver'
export default {
    name: 'smap',
    props: {
        formData:{}
        },
    data() {
        return {
            // 底图 图层变量
            baseMapLayer :{
                tileLayer: new ol.layer.Tile({
                source: new ol.source.OSM({
                url: "http://t{1-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=035b1c923e029e65a2de3c58d040b419"
                    })
                }),
                labelLayer: new ol.layer.Tile({
                    zIndex: 1,
                    source: new ol.source.OSM({
                    url: "http://t{1-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=035b1c923e029e65a2de3c58d040b419"
                    })
                })
            },
            //变量
            MyMap:undefined,
            selectSingleClick:{},
            wktLayers : {},
            vetorList : [],
            overlay :undefined,
            ///绘制的图层
            drawLayes:undefined,
            //分割规格
            radioValue:'48',
            //绘制对象
            fence:undefined,
            //绘出的路线
            drawLine:undefined,
            spacing:48,
            lo:0,
            // 坐标分割数组
            spacingArray:[],
            surplus:0,
            //格子列表
            blockList:[]

        };
    },
    watch:{
        clickMappicture(val){
            if (val!=0) {
                this.toImg()
            }
        },
        formData(val){
            if(val.theGeom){
            let center =this.setCent(val.theGeom);
            let view = this.MyMap.getView();
            view.setZoom(12)
            view.setCenter(center)
            this.clearWKT()
            this.drawWKT3(val)
        } 
        }
    },
    mounted() {
        this.createMap(this.setCent()); 
    },
    methods: {
        //设置中心点
        setCent(geo){
            if(geo){
               let coordinate = geo.replace('(',"").replace(")","").split(",")
               if(coordinate.length>2){
                   let point = coordinate[1].split(" ")
                   return [parseFloat(point[0]),parseFloat(point[1])]     
               }
                
            }
            else{
                return [113.94261734587297, 22.57669954443905]
            }
        },
        //截图
        toImg() {
            let that = this;
                this.MyMap.once('postcompose', function (event) {
                    var canvas = event.context.canvas;
                    canvas.toBlob(function (blob) {
                        that.$emit('selectPicture', blob,"map");
                        // saveAs(blob, 'map2.png')
                    })
                })
                this.MyMap.renderSync()
            },
        //点击开始画图
        drawRoad(){
            this.MyMap.removeLayer(this.drawLayes)
            this.fence = new drawFence(this.MyMap) 
            // fence.drawingFence('Polygon')
            this.drawLayes= this.fence.drawingFence('Polygon',this.drawingEnd)
            // console.log(this.drawLine)
        },
        //绘制结束调用
        drawingEnd(evt) {
            let geo = evt.feature.getGeometry()
            let type = geo.getType(); //获取类型
            // console.log(geo)
            //根据不同的类型执行不同的操作
            const handle = {
                'Circle': ()=> {
                    //获取中心点和半径
                    let center = geo.getCenter()
                    let radius = geo.getRadius()
                    this.drawLine = {center,radius}
                },
                'Polygon': () => {
                    //获取坐标点
                    let points = geo.getCoordinates()
                    this.drawLine = points
                },
                'LineString': () => {
                    let points = geo.getCoordinates()
                    this.drawLine = points
                }
            }
            if (handle[type]) handle[type]()
        },
        // 取消绘制
        cancelRoad(){
            if(this.fence){
                this.fence.closeDraw()
            }
            
            this.MyMap.removeLayer(this.drawLayes)
            this.spacingArray=[]
            this.clearWKT()
            
        },
        //计算并且绘格子
        computeBlock(){
            this.spacingArray=[]
            this.clearWKT()
            this.blockList = []
            if(!this.drawLine){
                this.Message({
                    message:"必须先绘出路线！",
                    type:'error'
                })
                return
            }
            let routrArray= this.drawLine;
            this.spacing =parseFloat(this.radioValue)
            this.surplus=0-this.spacing //剩下的距离
            for(var i=0;i<routrArray.length;i++){
				if(i>0){
					let newCoordinate = routrArray[i]
					let oldCoordinate = routrArray[i-1]
					this.surplus= this.getCoordinate(undefined,this.spacing,this.surplus,oldCoordinate,newCoordinate)
					if(i==(routrArray.length-1)){
						this.spacingArray[0].position = routrArray[i]
						// break
					}
				}
				else{
					let data={origin:routrArray[i],position:undefined}
					this.spacingArray.unshift(data)
				}
			}
            for(var i=0;i<this.spacingArray.length;i++){
				let one = this.spacingArray[i]
				let angle = this.getDegree(one.origin[1],one.origin[0],one.position[1],one.position[0])
				// console.log(angle)
				let poi1 = this.computerThatLonLat(one.origin[0],one.origin[1],angle,this.spacing)
				let poi2 =this.computerThatLonLat(one.origin[0],one.origin[1],angle-90.0,this.spacing/2)
				let poi3 =this.computerThatLonLat(one.origin[0],one.origin[1],angle-270.0,this.spacing/2)
				let poi4 =this.computerThatLonLat(poi2[0],poi2[1],angle, this.spacing)
				let poi5 =this.computerThatLonLat(poi3[0],poi3[1],angle, this.spacing)
				let polyeon = "POLYGON(("+poi2[0]+" "+poi2[1]+","+poi3[0]+" "+poi3[1]+","+poi5[0]+" "+poi5[1]+","+poi4[0]+" "+poi4[1]+"))"
				var areaBlock = {"theGeom":polyeon}
				var point2 = {"theGeom":"POINT("+poi4[0]+" "+poi4[1]+")"}
				this.drawWKT3(areaBlock)
				var line = {"theGeom":"LINESTRING("+one.origin[0]+" "+one.origin[1]+","+poi1[0]+" "+poi1[1]+")"}
				let reAngle = ""
				if(angle>90){
					reAngle =450.0 - angle
				}
				else{
					reAngle =90.0 - angle
				}
				let blockData=poi3[0]+","+poi3[1]+","+poi5[0]+","+poi5[1]+","+poi4[0]+","+poi4[1]+","+poi2[0]+","+poi2[1]+","+parseFloat(reAngle)+'\n'
				this.blockList.unshift(blockData)
				// drawWKT2(point6,"#000")
				// drawWKT2(point7,"#000")
				// drawWKT2(point8,"#000")
			}
			// console.log(JSON.stringify(this.blockList) )
        },
        //下载格子文件
        downloadFile(){
            this.clearWKT()
            this.$emit('saveDraw', this.drawLine);
            // var file = new File(this.blockList, "block.txt", {type: "text/plain;charset=utf-8"});
            // saveAs(file);
        },
        //路径分段分段 
        // distance 原距离 
        // spacing 分割断长度
        // surplus 前段剩余长度
        // oldCoordinate起始点坐标
        // 末尾点坐标
        getCoordinate(distance,spacing,surplus,oldCoordinate,newCoordinate){
            distance = distance?distance:this.GetDistance(oldCoordinate[1],oldCoordinate[0],newCoordinate[1],newCoordinate[0])
            if(surplus>0){  //前段距离超过50米，且剩余不足50m
                    // lo+=1
                    let scale = surplus/distance
                    let oldCoordinateY = parseFloat(oldCoordinate[1]) +(parseFloat(newCoordinate[1])-parseFloat(oldCoordinate[1]))*scale
                    let oldCoordinateX = parseFloat(oldCoordinate[0]) +(parseFloat(newCoordinate[0])-parseFloat(oldCoordinate[0]))*scale
                    let cood = oldCoordinateX+","+oldCoordinateY
                    
                    let b= [oldCoordinateX,oldCoordinateY]
                    // console.log(cood)
                    let b1= [oldCoordinate[0],oldCoordinate[1]]
                    let b2= [newCoordinate[0],newCoordinate[1]]
                    var point = {"theGeom":"POINT("+b[0]+" "+b[1]+")"}//折中点
                    var point1 = {"theGeom":"POINT("+b1[0]+" "+b1[1]+")"} //前一个点
                    var point2 = {"theGeom":"POINT("+b2[0]+" "+b2[1]+")"} //第二个点
                    // this.drawWKT2(point,"#FF0000")
                    // if(lo==0){
                        // this.drawWKT2(point1,"#61CC80")
                        // this.drawWKT2(point2,"#232B99")
                    //     console.log(spacingArray[0].origin)
                    // }
                    if(this.spacingArray[0].origin[0]==b1[0]&&this.spacingArray[0].origin[1]==b1[1]){
                        this.spacingArray[0].position = b2
                    }
                    else{
                        this.spacingArray[0].position = b1
                    }
                    let data={origin:b,position:undefined}
                    this.spacingArray.unshift(data)
                    if(distance-surplus>spacing){
                        distance = distance-surplus
                        this.surplus = spacing
                        this.surplus = this.getCoordinate(distance,spacing,this.surplus,[oldCoordinateX,oldCoordinateY],newCoordinate)
                    }
                    else{
                        this.surplus = distance- spacing-this.surplus
                        return this.surplus
                    }	
            }
            else{  //前段距离不足50米，
                if(distance>Math.abs(this.surplus)){ //后段大于
                    this.surplus = Math.abs(this.surplus)
                    this.surplus = this.getCoordinate(distance,spacing,this.surplus,oldCoordinate,newCoordinate)
                }
                else{ //且剩余不足50m
                    this.surplus = distance +this.surplus;
                    return this.surplus
                }
            }
            return this.surplus
        },
        // 通过两点坐标计算距离 方法定义 lat,lng
        GetDistance( lat1,  lng1,  lat2,  lng2){
            var radLat1 = lat1*Math.PI / 180.0;
            var radLat2 = lat2*Math.PI / 180.0;
            var a = radLat1 - radLat2;
            var  b = lng1*Math.PI / 180.0 - lng2*Math.PI / 180.0;
            var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
            Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
            s = s *6378.137 ;// EARTH_RADIUS;
            s = Math.round(s * 10000) / 10000;
            return s*1000;
        },
        //绘制图形
		drawWKT2(geomstring,color) {
				let wkt = geomstring.theGeom
				let format = new ol.format.WKT(wkt)
				let feature = format.readFeature(wkt)
				let vectorWKT = new ol.layer.Vector({
						source: new ol.source.Vector({
							features: [feature]
						}),
						opacity: 0.9,
						style:new ol.style.Style({
									image: new ol.style.Circle({
									  radius: 5,
									  fill: new ol.style.Fill({
											color: color
											})
									})
								})
				})
				 this.MyMap.addLayer(vectorWKT);
			},
        drawWKT3(geomstring,color) {
					let wkt = geomstring.theGeom
					let format = new ol.format.WKT(wkt)
					let feature = format.readFeature(wkt)
					let vectorWKT = new ol.layer.Vector({
							source: new ol.source.Vector({
								features: [feature]
							}),
							opacity: 0.9,
							style:new ol.style.Style({
								fill: new ol.style.Fill({
									color:'rgba(218,218,218, 0.1)',
								}),
								stroke:new ol.style.Stroke({
									color:"#000",
									width:1
								})
							})
					})
                    this.wktLayers[wkt] = vectorWKT
					this.MyMap.addLayer(vectorWKT);
				},
        //计算角度 北方向顺时针
	    getDegree(latA, lonA, latB, lonB){
            let radLatA = latA* Math.PI / 180.0;
            let radLonA = lonA* Math.PI / 180.0;
            let radLatB = latB* Math.PI / 180.0;
            let radLonB = lonB* Math.PI / 180.0;
            let dLon = radLonB - radLonA
            let y = Math.sin(dLon) * Math.cos(radLatB)
            let x = Math.cos(radLatA) * Math.sin(radLatB) - Math.sin(radLatA) * Math.cos(radLatB) * Math.cos(dLon)
            let brng = Math.atan2(y, x)* 180.0 / Math.PI;
            brng = (brng + 360.0) % 360.0
            // brng = brng.toFixed(2)
            return brng
	    },
        //通过距离、角度、坐标点计算另一个坐标位置
	    computerThatLonLat(lon,lat,brng,dist){
            	/** 长半径a=6378137 */
                var a = 6378137;
                /** 短半径b=6356752.3142 */
                var b = 6356752.3142;
                /** 扁率f=1/298.2572236 */
                var f = 1 / 298.2572236;
				var brng1 = brng
				if(brng<0){
					brng1 = (brng+360.0)
				}
				var alpha1 = brng1* Math.PI / 180.0;
				var sinAlpha1 = Math.sin(alpha1);
				var cosAlpha1 = Math.cos(alpha1);
				var tanU1 = (1 - f) * Math.tan(lat* Math.PI / 180.0);
				var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1));
				var sinU1 = tanU1 * cosU1;
				var sigma1 = Math.atan2(tanU1, cosAlpha1);
				var sinAlpha = cosU1 * sinAlpha1;
				var cosSqAlpha = 1 - sinAlpha * sinAlpha;
				var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
				var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
				var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
				var cos2SigmaM=0;
				var sinSigma=0;
				var cosSigma=0;
				var sigma = dist / (b * A), sigmaP = 2 * Math.PI;
				while (Math.abs(sigma - sigmaP) > 1e-12) {
					cos2SigmaM = Math.cos(2 * sigma1 + sigma);
					sinSigma = Math.sin(sigma);
					cosSigma = Math.cos(sigma);
					var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)
							- B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
					sigmaP = sigma;
					sigma = dist / (b * A) + deltaSigma;
				}
				var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
				var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
						(1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
				var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
				var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
				var L = lambda - (1 - C) * f * sinAlpha
						* (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
				var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
				return [lon+L* 180.0 / Math.PI,lat2* 180.0 / Math.PI]
	},
         //地图相关==================================================================
        createMap(cent) {
            let setCen = cent?cent:[113.94261734587297, 22.57669954443905]
            this.MyMap = new ol.Map({
                target: 'map',
                logo: false,
                layers: null,
                interactions: ol.interaction.defaults({
                    doubleClickZoom: false
                }),
                view: new ol.View({
                    projection: "EPSG:4326",
                    center: setCen,
                    zoom: 17,
                    minZoom: 2,  
                    maxZoom: 18.5
                }),
                controls: ol.control.defaults({
                        attributionOptions: ({
                        collapsible: false
                        })
                
                    })

            })
            let temp = null
            const mousePositionControl = new ol.control.MousePosition({
                coordinateFormat: function (coordinate) {
                temp = coordinate
                    return ol.coordinate.format(coordinate, '经度:{x}°E 纬度:{y}°N', 2)
                },
                projection: 'EPSG:4326',
                className: 'ol-mouse-position',
                target: document.getElementById('mouse-position'),
            })
            
            this.MyMap.addLayer(this.baseMapLayer.tileLayer) //矢量图
            this.MyMap.addLayer(this.baseMapLayer.labelLayer) //影像图
            // 监听地图单击
            // map.on('singleclick', evt => {
            // 	console.log(evt.coordinate)
            // })
            //弹出气泡
            var container = document.getElementById('popup');
            var content = document.getElementById('popup-content');

            this.overlay = new ol.Overlay({
                element: container,
                autoPan: true,
                autoPanAnimation: {
                    duration: 250,
                },
            });
            this.MyMap.addOverlay(this.overlay);
        },
        // 设置底图 地图切换
        setBaseMap (layer) {
            this.MyMap.removeLayer(this.baseMapLayer.tileLayer)
            this.MyMap.removeLayer(this.baseMapLayer.labelLayer)
            let source = null
            let type = layer.typeName
            let url = layer.url
            let labelSource = this.baseMapLayer.labelLayer.getSource()
            if (labelSource) {
               this.baseMapLayer.labelLayer.setSource(null)
            }
            if (type === 'tianditu' || type === 'xyz') {
                source = new ol.source.XYZ({
                // crossOrigin: 'anonymous',
                url: url.split('|')[0]
                })
                let labelSource = new ol.source.XYZ({
                // crossOrigin: 'anonymous',
                url: url.split('|')[1]
                })
                this.baseMapLayer.labelLayer.setZIndex(-1)
                this.baseMapLayer.labelLayer.setSource(labelSource)
            }
                this.baseMapLayer.tileLayer.setSource(source)
                this.baseMapLayer.tileLayer.setZIndex(-2)
                this.MyMap.addLayer(this.baseMapLayer.tileLayer)
                this.MyMap.addLayer(this.baseMapLayer.labelLayer)
                this.MyMap.index = -1
            },
        //绘制图形
        drawWKT(geomstring) {
                let wkt = geomstring.theGeom
                let format = new ol.format.WKT(wkt)
                let feature = format.readFeature(wkt)
                const geoType = this.getGeoType(wkt); //判断数据点线面
                // let mycolor = geomstring.showColor
                let vectorWKT = new ol.layer.Vector({
                        source: new ol.source.Vector({
                            features: [feature]
                        }),
                        opacity: 0.9,
                        style:FeatureStyle.getStyle(geoType,geomstring.abStatus)
                })
                this.MyMap.removeInteraction(this.selectSingleClick);//移除之前的图层
                this.vetorList.push(vectorWKT)
                // selectSingles[geomstring.ID+geomstring.name] = selectSingleClick;
                // this.MyMap.addInteraction(this.selectSingleClick);
                // this.MyMap.selectSingleClick =this.selectSingleClick;
                // this.selectSingleClick.on('select', this.poiClick); //图层点击
                // this.wktLayers[geomstring[objId]+geomstring[objName]] = vectorWKT
                this.MyMap.addLayer(vectorWKT);
            },
        //移除绘制图层
        removeWKT (geomstring,objId,objName) {
            let wkt = geomstring[objId]+geomstring[objName]
            if(this.wktLayers[wkt]!=undefined) {
                let index = this.vetorList.indexOf(this.wktLayers[wkt])
                index>-1&&this.vetorList.splice(index, 1);
                this.MyMap.removeLayer(this.wktLayers[wkt])
                this.overlay.setPosition(undefined);
                delete this.wktLayers[wkt]
                }
            },
        clearWKT () {
            this.vetorList=[]
            Object.keys(this.wktLayers).forEach(key => {
                this.MyMap.removeLayer(this.wktLayers[key])
                delete this.wktLayers[key]
                })
            },
        //数据类型判断
        getGeoType(geo){
                if(geo.indexOf("POLYGON")!=-1){
                    return "POLYGON"
                }
                else if(geo.indexOf("LINESTRING")!=-1){
                    return "LINESTRING"
                }
                else if(geo.indexOf("minLine")!=-1){
                    return "minLine"
                }
                else if(geo.indexOf("POINT")!=-1){
                    return "ICON"
                }
                else if(geo.indexOf("ICON")!=-1){
                    return "ICON"
                }
                else if(geo.indexOf("oldICON")!=-1){
                    return "oldICON"
                }
                else{
                    return ""
                }
            }
    },
};
</script>

<style lang="scss" scoped>
.map-box{
    position: relative;
    width: 100%;
    height: 100%;
}
.myMap{
    position: absolute;
    height: 100%;
    width: 100%;
    box-sizing: border-box;
}
.upload{
    position: absolute;
    bottom: 0px;
    right: 40%;
}
.drawBox{
    width: 350px;
    height: 50px;
    background: rgba($color: #fff, $alpha: 0.8);
    position: absolute;
    left: 5px;
    top: 5px;
    padding: 10px;
    .drawText{
        margin-right: 10px;
    }
    .lastRow{
        button{
            margin-right: 18px
        }
    }
}
</style>